﻿using Vowei.Web.Controllers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting.Web;
using System.Web.Mvc;
using Vowei.Core.Models;
using Vowei.Data;
using System.Linq;
using Vowei.Data.Models;
using Vowei.Data.Helpers;
using Vowei.Web.Models;
using Vowei.Web.Helpers;
using System.IO;
using Vowei.Data.Converters.Excel;

namespace vowei.test
{
    [TestClass()]
    public class RequirementControllerTest : TestBase
    {
        [TestMethod]
        public void CreateRequirementAndViewTimelineIntergrationTest()
        {
            // 创建一个新的项目
            var pid = Guid.Empty;
            using (var impl = new VoweiContextImpl())
            {
                var project = new Project()
                {
                    Title = "CreateRequirementAndViewTimelineIntergrationTest_Project",
                    Owner = Setting.DefaultUserName
                };

                impl.Projects.Add(project);
                impl.SaveChanges();

                pid = project.ID;
            }

            var requirement = new Requirement()
            {
                Title = "CreateRequirementAndViewTimelineIntergrationTest_Requirement",
                AssignedTo = Setting.DefaultUserName,
                BelongsToMilestone = new Project() { ID = pid }
            };
            var rcontroller = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            var actual = rcontroller.Create(requirement);
            var result = actual as RedirectToRouteResult;
            Assert.IsNotNull(result);

            using (var impl = new VoweiContextImpl())
            {
                var context = new VoweiContext(impl);
                var project = impl.Projects.Find(pid);
                var progresses = MilestoneProgress.CreateFrom(project, context);
                
                Assert.AreEqual(1, progresses.ActiveTicketCount);
                Assert.AreEqual(0, progresses.ClosedTicketCount);
                Assert.AreEqual(1, progresses.TicketCount);
            }
        }
        
        [TestMethod]
        [Description("在需求里面有任务关联，然后再执行统计")]
        public void CreateRequirementWithTaskAndViewTimelineIntergrationTest()
        {
            // 创建一个新的项目
            var pid = Guid.Empty;
            var tid = Guid.Empty;
            using (var impl = new VoweiContextImpl())
            {
                var project = new Project()
                {
                    Title = "CreateRequirementWithTaskAndViewTimelineIntergrationTest_Project",
                    Owner = Setting.DefaultUserName
                };

                impl.Projects.Add(project);
                impl.SaveChanges();
                pid = project.ID;

                var task = new Task()
                {
                    Title = "CreateRequirementWithSubTasksTest_Task",
                    AssignedTo = Setting.DefaultUserName
                };
                impl.Tasks.Add(task);
                impl.SaveChanges();
                tid = task.ID;
            }

            var requirement = new Requirement()
            {
                Title = "CreateRequirementWithTaskAndViewTimelineIntergrationTest_Requirement",
                AssignedTo = Setting.DefaultUserName,
                BelongsToMilestone = new Project() { ID = pid }
            };
            requirement.Children.Add(new Task() { ID = tid });
            var rcontroller = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            var actual = rcontroller.Create(requirement);
            var result = actual as RedirectToRouteResult;
            Assert.IsNotNull(result);

            using (var impl = new VoweiContextImpl())
            {
                var project = impl.Projects.Find(pid);
                var context = new VoweiContext(impl);
                var progresses = MilestoneProgress.CreateFrom(project, context);

                Assert.AreEqual(2, progresses.ActiveTicketCount);
                Assert.AreEqual(0, progresses.ClosedTicketCount);
                Assert.AreEqual(2, progresses.TicketCount);
            }
        }

        [TestMethod]
        [Description("创建一个项目，里面有里程碑，项目和里程碑都是关联的")]
        public void CreateRequirementAndViewTimelineMilestoneIntergrationTest()
        {
            // 创建一个新的项目
            var pid = Guid.Empty;
            var mid = Guid.Empty;
            using (var impl = new VoweiContextImpl())
            {
                var project = new Project()
                {
                    Title = "CreateRequirementAndViewTimelineMilestoneIntergrationTest_Project",
                    Owner = Setting.DefaultUserName
                };
                impl.Projects.Add(project);

                pid = project.ID;

                var milestone = new Milestone()
                {
                    Title = "CreateRequirementAndViewTimelineMilestoneIntergrationTest_Milestone"
                };
                impl.Milestones.Add(milestone);
                project.Children.Add(milestone);
                impl.SaveChanges();

                mid = milestone.ID;
            }

            var requirement = new Requirement()
            {
                Title = "CreateRequirementAndViewTimelineMilestoneIntergrationTest_RequirementP",
                AssignedTo = Setting.DefaultUserName,
                BelongsToMilestone = new Project() { ID = pid }
            };
            var rcontroller = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            var actual = rcontroller.Create(requirement);
            var result = actual as RedirectToRouteResult;
            Assert.IsNotNull(result);

            requirement = new Requirement()
            {
                Title = "CreateRequirementAndViewTimelineMilestoneIntergrationTest_RequirementM",
                AssignedTo = Setting.DefaultUserName,
                BelongsToMilestone = new Project() { ID = mid }
            };
            result = rcontroller.Create(requirement) as RedirectToRouteResult;
            Assert.IsNotNull(result);
            
            using (var impl = new VoweiContextImpl())
            {
                var project = impl.Projects.Find(pid);
                var context = new VoweiContext(impl);
                var progresses = MilestoneProgress.CreateFrom(project, context);

                Assert.AreEqual(2, progresses.ActiveTicketCount);
                Assert.AreEqual(0, progresses.ClosedTicketCount);
                Assert.AreEqual(2, progresses.TicketCount);

                // 下面这一个几个验证是期望它失败的，因为MilestoneProgress.CreateFrom
                // 完全是使用Linq实现的查询，等实际移植到数据库上，使用存储过程实现
                // MilestoneProgress.CreateFrom的功能后，下面这些验证就应该能够通过了。
                Assert.AreEqual(1, progresses.Children.Count);
                Assert.AreEqual(1, progresses.Children[0].ActiveTicketCount);
                Assert.AreEqual(0, progresses.Children[0].ClosedTicketCount);
                Assert.AreEqual(1, progresses.Children[0].TicketCount);
            }
        }

        [TestMethod]
        public void EditItemBasicTest()
        {
            var id = Guid.Empty;
            var pid = Guid.Empty;

            var project = GetDefaultProject(VoweiContext);
            pid = project.ID;
            var requirement = new Requirement()
            {
                Title = "EditItemBasicTest_Requirement",
                AssignedTo = Setting.DefaultUserName,
                BelongsToMilestone = project
            };
            id = requirement.ID;
            VoweiContext.Requirements.Add(requirement);
            VoweiContext.SaveChanges();

            var target = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            var result = target.Edit(id) as ViewResult;
            Assert.IsNotNull(result);

            var actual = result.Model as Requirement;
            Assert.IsNotNull(actual);
            Assert.IsTrue(id.CompareTo(actual.ID) == 0);
            Assert.IsNotNull(actual.BelongsToMilestone);

            var milestone = result.ViewData["Milestones"] as string;
            Assert.IsNotNull(milestone);

            Assert.IsTrue(milestone.Contains(pid.ToString()));
        }

        [TestMethod]
        public void CreateWithProjectHasNoMilestoneTest()
        {
            var project = new Project()
            {
                Title = "CreateWithProjectHasNoMilestoneTest_Project",
                Owner = Setting.DefaultUserName
            };

            using (var impl = new VoweiContextImpl())
            {
                impl.Projects.Add(project);
                impl.SaveChanges();
            }

            var target = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            var actual = target.CreateIn(project.ID) as ViewResult;

            Assert.IsNotNull(actual);
            Assert.IsNotNull(actual.Model);

            var milestone = actual.ViewData["Milestones"] as string;
            Assert.IsNotNull(milestone);

            Assert.IsTrue(milestone.Contains(project.ID.ToString()));
        }

        [TestMethod]
        public void CreateWithProjectNotAddedToTimelineNodeTest()
        {
            var project = new Project()
            {
                Title = "CreateWithProjectNotAddedToTimelineNodeTest_Project",
                Owner = Setting.DefaultUserName
            };

            using (var impl = new VoweiContextImpl())
            {
                impl.Projects.Add(project);
                impl.SaveChanges();
            }

            var target = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            var actual = target.CreateIn(project.ID) as ViewResult;

            Assert.IsNotNull(actual);
        }

        [TestMethod]
        public void CreateWithProjectHasMilestoneTest()
        {
            Project project = null;
            Guid expectedMId = Guid.Empty;

            using (var impl = new VoweiContextImpl())
            {
                var context = new VoweiContext(impl);
                project = GetDefaultProject(impl);
                expectedMId = project.AllMilestones(context).First().ID;
            }

            var target = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            var actual = target.CreateIn(project.ID) as ViewResult;

            Assert.IsNotNull(actual);
            Assert.IsNotNull(actual.Model);

            var milestone = actual.ViewData["Milestones"] as string;
            Assert.IsNotNull(milestone);

            Assert.IsTrue(milestone.Contains(project.ID.ToString()));
            Assert.IsTrue(milestone.Contains(expectedMId.ToString()));
        }

        [TestMethod]
        [Description("创建一个带子任务的需求，看看Details是否能够将子任务检索出来")]
        public void BrowseNewlyCreatedRequirementWithChildrenTest()
        {
            var tid = Guid.Empty;
            var pid = Guid.Empty;
            var rid = Guid.Empty;

            var project = GetDefaultProject(VoweiContext);
            var task = new Task()
            {
                Title = "BrowseNewlyCreatedRequirementWithChildrenTest_Task",
                AssignedTo = Setting.DefaultUserName
            };
            var requirement = new Requirement()
            {
                Title = "CreateRequirementWithSubTasksTest_Requirement",
                AssignedTo = Setting.DefaultUserName,
                BelongsToMilestone = project
            };
            requirement.Children.Add(task);
            tid = task.ID;
            pid = project.ID;
            rid = requirement.ID;

            VoweiContext.Requirements.Add(requirement);
            VoweiContext.SaveChanges();

            var target = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            var result = target.Details(rid) as ViewResult;

            Assert.IsNotNull(result);
            Assert.IsNotNull(result.ViewData.Model);

            var actual = result.ViewData.Model as Requirement;
            Assert.IsNotNull(actual);
            Assert.IsTrue(rid.CompareTo(actual.ID) == 0);
            Assert.IsTrue(pid.CompareTo(actual.BelongsToMilestone.ID) == 0);
            Assert.AreEqual(1, actual.Children.Count());
            Assert.IsTrue(tid.CompareTo(actual.Children.ElementAt(0).ID) == 0);
        }

        [TestMethod]
        [Description("创建一个带子任务的需求，看看Pre Edit是否能够将子任务检索出来")]
        public void EditCreatedRequirementWithChildrenTest()
        {
            var tid = Guid.Empty;
            var pid = Guid.Empty;
            var rid = Guid.Empty;

            var project = GetDefaultProject(VoweiContext);
            var task = new Task()
            {
                Title = "BrowseNewlyCreatedRequirementWithChildrenTest_Task",
                AssignedTo = Setting.DefaultUserName
            };
            var requirement = new Requirement()
            {
                Title = "CreateRequirementWithSubTasksTest_Requirement",
                AssignedTo = Setting.DefaultUserName,
                BelongsToMilestone = project
            };
            requirement.Children.Add(task);
            tid = task.ID;
            pid = project.ID;
            rid = requirement.ID;

            VoweiContext.Requirements.Add(requirement);
            VoweiContext.SaveChanges();

            var target = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            var result = target.Edit(rid) as ViewResult;

            Assert.IsNotNull(result);
            Assert.IsNotNull(result.ViewData.Model);

            var actual = result.ViewData.Model as Requirement;
            Assert.IsNotNull(actual);
            Assert.IsTrue(rid.CompareTo(actual.ID) == 0);
            Assert.IsTrue(pid.CompareTo(actual.BelongsToMilestone.ID) == 0);
            Assert.AreEqual(1, actual.Children.Count());
            Assert.IsTrue(tid.CompareTo(actual.Children.ElementAt(0).ID) == 0);
        }

        [TestMethod]
        public void EditRequirementMilestoneTest()
        {
            var rid = Guid.Empty;
            var mid = Guid.Empty;
            using (var impl = new VoweiContextImpl())
            {
                var project = GetDefaultProject(impl);
                var context = new VoweiContext(impl);
                var requirement = CreateRequirementHelper("EditRequirementMilestoneTest", project);
                impl.Requirements.Add(requirement);
                impl.SaveChanges();

                var milestone = project.AllMilestones(context).First();
                requirement.BelongsToMilestone = (Milestone)milestone;
                impl.SaveChanges();

                rid = requirement.ID;
                mid = milestone.ID;
            }

            using (var impl = new VoweiContextImpl())
            {
                var requirement = impl.Requirements.Include("BelongsToMilestone").Single(r => r.ID == rid);
                Assert.IsTrue(mid.CompareTo(requirement.BelongsToMilestone.ID) == 0);

                var project = CreateProjectHelper("EditRequirementMilestoneTest");
                requirement.BelongsToMilestone = project;
                impl.SaveChanges();
                mid = project.ID;
            }

            using (var impl = new VoweiContextImpl())
            {
                var requirement = impl.Requirements.Include("BelongsToMilestone").Single(r => r.ID == rid);
                Assert.IsTrue(mid.CompareTo(requirement.BelongsToMilestone.ID) == 0);
            }
        }

        [TestMethod]
        public void CreateDetailsIntergrationTest()
        {
            var tid = Guid.Empty;
            var pid = Guid.Empty;
            var rid = Guid.Empty;

            using (var impl = new VoweiContextImpl())
            {
                var project = GetDefaultProject(impl);
                var task = new Task()
                {
                    Title = "CreateDetailsIntergrationTest_Task",
                    AssignedTo = Setting.DefaultUserName
                };
                impl.Tasks.Add(task);
                impl.SaveChanges();
                tid = task.ID;
                pid = project.ID;
            }
            var requirement = new Requirement()
            {
                Title = "CreateDetailsIntergrationTest_Requirement",
                AssignedTo = Setting.DefaultUserName,
                BelongsToMilestone = new Milestone() { ID = pid }
            };
            requirement.Children.Add(new Task() { ID = tid });
            rid = requirement.ID;
            var controller = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            var result = controller.Create(requirement);

            result = controller.Details(rid);
            Assert.IsTrue(result is ViewResult);
            var actual = ((ViewResult)result).Model as Requirement;
            Assert.IsNotNull(actual);
            Assert.IsTrue(rid.CompareTo(actual.ID) == 0);
            Assert.AreEqual(1, actual.Children.Count());
            Assert.IsTrue(pid.CompareTo(actual.BelongsToMilestone.ID) == 0);
            Assert.IsTrue(tid.CompareTo(actual.Children.ElementAt(0).ID) == 0);
        }

        [TestMethod]
        public void EditDetailsIntergrationTest()
        {
            var tid = Guid.Empty;
            var pid = Guid.Empty;
            var rid = Guid.Empty;

            using (var impl = new VoweiContextImpl())
            {
                var project = GetDefaultProject(impl);
                var task = new Task()
                {
                    Title = "EditDetailsIntergrationTest_Task",
                    AssignedTo = Setting.DefaultUserName
                };
                var req = new Requirement()
                {
                    Title = "EditDetailsIntergrationTest_Requirement",
                    AssignedTo = Setting.DefaultUserName,
                    BelongsToMilestone = project
                };
                tid = task.ID;
                pid = project.ID;
                rid = req.ID;

                impl.Requirements.Add(req);
                impl.Tasks.Add(task);
                impl.SaveChanges();
            }

            using (var impl = new VoweiContextImpl())
            {
                var controller = new RequirementController(new VoweiContext(impl), Setting.DefaultFormUser);
                var result = controller.Edit(rid);
                Assert.IsTrue(result is ViewResult);
                var requirement = ((ViewResult)result).Model as Requirement;
                Assert.IsNotNull(requirement);
                Assert.AreEqual(requirement.BelongsToMilestoneId, pid);
                // Assert.IsNotNull(requirement.BelongsToMilestone);
                var changedRequirement = CloneRequirementHelper(requirement);

                changedRequirement.Children.Add(new Ticket() { ID = tid });
                result = controller.Edit(changedRequirement);
                Assert.IsTrue(result is RedirectToRouteResult);

                result = controller.Details(rid);
                Assert.IsTrue(result is ViewResult);
                var actual = ((ViewResult)result).Model as Requirement;
                Assert.IsNotNull(actual);
                Assert.IsTrue(rid.CompareTo(actual.ID) == 0);
                Assert.AreEqual(1, actual.Children.Count());
                Assert.IsTrue(pid.CompareTo(actual.BelongsToMilestoneId) == 0);
                Assert.IsTrue(tid.CompareTo(actual.Children.ElementAt(0).ID) == 0);
            }
        }

        [TestMethod]
        public void AddChildTicketToRequirementTest()
        {
            Requirement expected = null;
            var tid1 = Guid.Empty;
            var tid2 = Guid.Empty;
            using (var impl = new VoweiContextImpl())
            {
                var project = GetDefaultProject(impl);
                var req = new Requirement()
                {
                    Title = "AddChildTicketToRequirementTest_Requirement",
                    AssignedTo = Setting.DefaultUserName,
                    BelongsToMilestone = project
                };
                var task = new Task()
                {
                    Title = "AddChildTicketToRequirementTest_AlreadyExistedTask",
                    AssignedTo = Setting.DefaultUserName
                };
                req.Children.Add(task);
                impl.Requirements.Add(req);
                tid1 = task.ID;

                task = new Task()
                {
                    Title = "AddChildTicketToRequirementTest_NewTask",
                    AssignedTo = Setting.DefaultUserName
                };
                impl.Tasks.Add(task);
                impl.SaveChanges();
                tid2 = task.ID;

                expected = new Requirement()
                {
                    ID = req.ID,
                    Title = req.Title,
                    AssignedTo = req.AssignedTo,
                    BelongsToMilestone = req.BelongsToMilestone,
                    OpenDate = req.OpenDate,
                    Reporter = req.Reporter,
                    BusinessValue = req.BusinessValue
                };
            }

            expected.Children.Add(new Task() { ID = tid1 });
            expected.Children.Add(new Task() { ID = tid2 });
            var controller = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            var result = controller.Edit(expected);
            Assert.IsTrue(result is RedirectToRouteResult);

            using (var impl = new VoweiContextImpl())
            {
                var actual = impl.Find<Requirement>(expected.ID);
                Assert.AreEqual(2, actual.Children.Count());
                Assert.IsTrue(
                    actual.Children.Any(c => tid1.CompareTo(c.ID) == 0));
            }
        }

        [TestMethod]
        public void AddChildTicketToRequirementFromUITest()
        {
            var expected = new Requirement()
            {
                Title = "AddChildTicketToRequirementFromUITest_Requirement",
                AssignedTo = Setting.DefaultUserName,
            };
            var tid1 = Guid.Empty;
            var tid2 = Guid.Empty;
            var project = GetDefaultProject(VoweiContext);
            expected.BelongsToMilestone = project;
            var task = new Task()
            {
                Title = "AddChildTicketToRequirementFromUITest_AlreadyExistedTask",
                AssignedTo = Setting.DefaultUserName
            };
            VoweiContext.Tasks.Add(task);
            tid1 = task.ID;

            task = new Task()
            {
                Title = "AddChildTicketToRequirementFromUITest_NewTask",
                AssignedTo = Setting.DefaultUserName
            };
            VoweiContext.Tasks.Add(task);
            VoweiContext.SaveChanges();
            tid2 = task.ID;

            var controller = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            expected.Children.Add(new Task() { ID = tid1 });
            var result = controller.Create(expected);
            Assert.IsTrue(result is RedirectToRouteResult);

            var changedRequirement = CloneRequirementHelper(expected);
            changedRequirement.Children.Add(new Task() { ID = tid2 });
            result = controller.Edit(changedRequirement);
            Assert.IsTrue(result is RedirectToRouteResult);

            using (var impl = new VoweiContextImpl())
            {
                var actual = impl.Find<Requirement>(expected.ID);
                Assert.AreEqual(2, actual.Children.Count());
                Assert.IsTrue(
                    actual.Children.Any(c => tid1.CompareTo(c.ID) == 0));
            }
        }

        [TestMethod]
        public void RemoveChildTicketFromRequirementTest()
        {
            Requirement expected = null;
            var tid = Guid.Empty;
            using (var impl = new VoweiContextImpl())
            {
                var project = GetDefaultProject(impl);
                expected = new Requirement()
                {
                    Title = "RemoveChildTicketFromRequirementTest_Requirement",
                    AssignedTo = Setting.DefaultUserName,
                    BelongsToMilestone = project
                };
                var task = new Task()
                {
                    Title = "RemoveChildTicketFromRequirementTest_Task1",
                    AssignedTo = Setting.DefaultUserName
                };
                expected.Children.Add(task);
                expected.Children.Add(new Task()
                {
                    Title = "RemoveChildTicketFromRequirementTest_Task2",
                    AssignedTo = Setting.DefaultUserName
                });
                impl.Requirements.Add(expected);
                impl.SaveChanges();
                tid = task.ID;
            }
                        
            expected.Children.Remove(expected.Children.ElementAt(0));
            var controller = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            var result = controller.Edit(expected);
            Assert.IsTrue(result is RedirectToRouteResult);

            using (var impl = new VoweiContextImpl())
            {
                var actual = impl.Find<Requirement>(expected.ID);
                Assert.AreEqual(1, actual.Children.Count());
                Assert.IsFalse(
                    actual.Children.Any(c => tid.CompareTo(c.ID) == 0));
            }

            expected.Children.Clear();
            result = controller.Edit(expected);
            Assert.IsTrue(result is RedirectToRouteResult);

            using (var impl = new VoweiContextImpl())
            {
                var actual = impl.Find<Requirement>(expected.ID);
                Assert.AreEqual(0, actual.Children.Count());
            }
        }

        [TestMethod]
        public void AddRemoveChildTicketFromRequirementTest()
        {
            Requirement expected = null;
            var tid1 = Guid.Empty;
            var tid3 = Guid.Empty;
            using (var impl = new VoweiContextImpl())
            {
                var project = GetDefaultProject(impl);
                expected = new Requirement()
                {
                    Title = "AddRemoveChildTicketFromRequirementTest_Requirement",
                    AssignedTo = Setting.DefaultUserName,
                    BelongsToMilestone = project
                };
                var task = new Task()
                {
                    Title = "AddRemoveChildTicketFromRequirementTest_Task1",
                    AssignedTo = Setting.DefaultUserName
                };
                tid1 = task.ID;
                expected.Children.Add(task);
                expected.Children.Add(new Task()
                {
                    Title = "AddRemoveChildTicketFromRequirementTest_Task2",
                    AssignedTo = Setting.DefaultUserName
                });
                impl.Requirements.Add(expected);

                task = new Task()
                {
                    Title = "AddRemoveChildTicketFromRequirementTest_Task3",
                    AssignedTo = Setting.DefaultUserName
                };
                tid3 = task.ID;
                impl.Tasks.Add(task);
                impl.SaveChanges();
            }

            expected.Children.Remove(expected.Children.ElementAt(0));
            var controller = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            var result = controller.Edit(expected);
            Assert.IsTrue(result is RedirectToRouteResult);

            expected.Children.Add(new Task() { ID = tid3 });
            result = controller.Edit(expected);
            Assert.IsTrue(result is RedirectToRouteResult);

            using (var impl = new VoweiContextImpl())
            {
                var actual = impl.Requirements.Include("Children").First(r => r.ID == expected.ID);
                Assert.AreEqual(2, actual.Children.Count());
                Assert.IsFalse(
                    actual.Children.Any(c => tid1.CompareTo(c.ID) == 0));
                Assert.IsTrue(
                    actual.Children.Any(c => tid3.CompareTo(c.ID) == 0));
            }
        }

        [TestMethod]
        public void PostEditRequirementTest()
        {
            Requirement requirement = null;
            var target = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            using (var impl = new VoweiContextImpl())
            {
                var project = CreateProjectHelper("PostEditRequirementTest");
                requirement = CreateRequirementHelper("PostEditRequirementTest", project);
                impl.Projects.Add(project);
                impl.Requirements.Add(requirement);

                impl.SaveChanges();
            }

            var expectedTitle = "PostEditRequirementTest_Title";
            var expectedBizValue = 12345;

            requirement.Title = expectedTitle;
            requirement.BusinessValue = expectedBizValue;
            var result = target.Edit(requirement) as RedirectToRouteResult;

            Assert.IsNotNull(result);

            using (var impl = new VoweiContextImpl())
            {
                var actual = impl.Requirements.Find(requirement.ID);
                Assert.AreEqual(expectedTitle, actual.Title);
                Assert.AreEqual(expectedBizValue, actual.BusinessValue);
            }
        }

        [TestMethod]
        public void PostEditRequirementWithChildrenTest()
        {
            Requirement requirement = null;
            var target = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            using (var impl = new VoweiContextImpl())
            {
                var project = CreateProjectHelper("PostEditRequirementWithChildrenTest");
                requirement = CreateRequirementHelper("PostEditRequirementWithChildrenTest", project);
                requirement.Children.Add(CreateRequirementHelper("PostEditRequirementWithChildrenTest_ChildRequirement", project));
                requirement.Children.Add(CreateTaskHelper("PostEditRequirementWithChildrenTest", project));
                impl.Projects.Add(project);
                impl.Requirements.Add(requirement);

                impl.SaveChanges();
            }

            var expectedTitle = "PostEditRequirementWithChildrenTest_Title";
            var expectedBizValue = 12345;

            requirement.Title = expectedTitle;
            requirement.BusinessValue = expectedBizValue;
            var result = target.Edit(requirement) as RedirectToRouteResult;

            Assert.IsNotNull(result);

            using (var impl = new VoweiContextImpl())
            {
                var actual = impl.Requirements.Find(requirement.ID);
                Assert.AreEqual(expectedTitle, actual.Title);
                Assert.AreEqual(expectedBizValue, actual.BusinessValue);
            }
        }

        [TestMethod]
        public void PostEditRequirementWithFakeChildrenTest()
        {
            Requirement requirement = null;
            Guid rid = Guid.Empty;
            Guid tid = Guid.Empty;
            var target = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            using (var impl = new VoweiContextImpl())
            {
                var project = CreateProjectHelper("PostEditRequirementWithChildrenTest");
                requirement = CreateRequirementHelper("PostEditRequirementWithChildrenTest", project);
                requirement.Children.Add(CreateRequirementHelper("PostEditRequirementWithChildrenTest_ChildRequirement", project));
                rid = requirement.Children.ElementAt(0).ID;
                requirement.Children.Add(CreateTaskHelper("PostEditRequirementWithChildrenTest", project));
                tid = requirement.Children.ElementAt(1).ID;
                impl.Projects.Add(project);
                impl.Requirements.Add(requirement);

                impl.SaveChanges();
            }

            var expectedTitle = "PostEditRequirementWithChildrenTest_Title";
            var expectedBizValue = 12345;

            requirement.Title = expectedTitle;
            requirement.BusinessValue = expectedBizValue;
            requirement.Children.Clear();
            requirement.Children.Add(new Requirement() { ID = rid });
            requirement.Children.Add(new Task() { ID = tid });
            var result = target.Edit(requirement) as RedirectToRouteResult;

            Assert.IsNotNull(result);

            using (var impl = new VoweiContextImpl())
            {
                var actual = impl.Requirements.Find(requirement.ID);
                Assert.AreEqual(expectedTitle, actual.Title);
                Assert.AreEqual(expectedBizValue, actual.BusinessValue);
            }
        }

        [TestMethod]
        public void PostEditRequirementWithFakeChildrenAndMilestoneTest()
        {
            Requirement requirement = null;
            Guid rid = Guid.Empty;
            Guid tid = Guid.Empty;
            var target = new RequirementController(VoweiContext, Setting.DefaultFormUser);
            using (var impl = new VoweiContextImpl())
            {
                var project = CreateProjectHelper("PostEditRequirementWithFakeChildrenAndMilestoneTest");
                requirement = CreateRequirementHelper("PostEditRequirementWithFakeChildrenAndMilestoneTest", project);
                requirement.Children.Add(CreateRequirementHelper("PostEditRequirementWithFakeChildrenAndMilestoneTest_ChildRequirement", project));
                rid = requirement.Children.ElementAt(0).ID;
                requirement.Children.Add(CreateTaskHelper("PostEditRequirementWithFakeChildrenAndMilestoneTest", project));
                tid = requirement.Children.ElementAt(1).ID;
                impl.Projects.Add(project);
                impl.Requirements.Add(requirement);

                impl.SaveChanges();
            }

            var expectedTitle = "PostEditRequirementWithFakeChildrenAndMilestoneTest_Title";
            var expectedBizValue = 12345;

            requirement.Title = expectedTitle;
            requirement.BusinessValue = expectedBizValue;
            requirement.BelongsToMilestone = new Milestone { ID = requirement.BelongsToMilestone.ID };
            requirement.Children.Clear();
            requirement.Children.Add(new Requirement() { ID = rid });
            requirement.Children.Add(new Task() { ID = tid });
            var result = target.Edit(requirement) as RedirectToRouteResult;

            Assert.IsNotNull(result);

            using (var impl = new VoweiContextImpl())
            {
                var actual = impl.Requirements.Find(requirement.ID);
                Assert.AreEqual(expectedTitle, actual.Title);
                Assert.AreEqual(expectedBizValue, actual.BusinessValue);
            }
        }
    }
}
